﻿using DevExpress.Data.Filtering;
using System.Linq.Dynamic.Core;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Domain.Repositories;
using Volo.Abp.Domain.Services;
using Volo.Abp.Linq;
using Volo.Abp.Uow;
using YAPACS.BusinessObjects.Exams;
using YAPACS.BusinessObjects.Services;
using YAPACS.RisServer.Abstractions;
using YAPACS.RisServer.Services.Dtos;
using YAPACS.Workflows;

namespace YAPACS.RisServer.Services;

public class TabPanelService(IUnitOfWorkManager unitOfWorkManager, IRepository<Exam, Guid> examRepository, IRepository<Report, Guid> reportRepository,
    IExamListService examListService,
    Workflows.TabPanel.Exam.IGetAdvancedSearchView getExamAdvancedSearchView,
    Workflows.TabPanel.Exam.IAdvancedSearchExpression examAdvancedSearchExpression,
    Workflows.TabPanel.Exam.IGetHeaders getExamHeaders,
    Workflows.TabPanel.Queue.IGetAdvancedSearchView getQueueAdvancedSearchView,
    Workflows.TabPanel.Queue.IAdvancedSearchExpression queueAdvancedSearchExpression,
    Workflows.TabPanel.Queue.IGetHeaders getQueueHeaders, IStationCodeProvider stationCodeProvider, Workflows.TabPanel.Queue.IExpression expression, 
    Workflows.TabPanel.Queue.IGetDefaultFilter getDefaultFilter)
    : DomainService, ITabPanelService, ITransientDependency
{
    private readonly IUnitOfWorkManager _unitOfWorkManager = unitOfWorkManager;
    private readonly IRepository<Exam, Guid> _examRepository = examRepository;
    private readonly IRepository<Report, Guid> _reportRepository = reportRepository;
    private readonly IExamListService _examListService = examListService;
    private readonly Workflows.TabPanel.Exam.IGetAdvancedSearchView _getExamAdvancedSearchView = getExamAdvancedSearchView;
    private readonly Workflows.TabPanel.Exam.IAdvancedSearchExpression _examAdvancedSearchExpression = examAdvancedSearchExpression;
    private readonly Workflows.TabPanel.Exam.IGetHeaders _getExamHeaders = getExamHeaders;
    private readonly Workflows.TabPanel.Queue.IGetAdvancedSearchView _getQueueAdvancedSearchView = getQueueAdvancedSearchView;
    private readonly Workflows.TabPanel.Queue.IAdvancedSearchExpression _queueAdvancedSearchExpression = queueAdvancedSearchExpression;
    private readonly Workflows.TabPanel.Queue.IGetHeaders _getQueueHeaders = getQueueHeaders;
    private readonly IStationCodeProvider _stationCodeProvider = stationCodeProvider;
    private readonly Workflows.TabPanel.Queue.IExpression _expression = expression;
    private readonly Workflows.TabPanel.Queue.IGetDefaultFilter _getDefaultFilter = getDefaultFilter;
    public async Task<WorkflowOutput> GetExamHistoriesAsync(Guid reportId, DataGridRequest request)
    {
        //获取当前患者
        try
        {
            var report = await _reportRepository.GetAsync(reportId);
            if (report.Exam.Patient == null)
            {
                throw new Exception("未找到患者数据");
            }
            var query = await _examRepository.GetQueryableAsync();
            query = query.Where(e => e.Patient.IdCardNumber == report.Exam.Patient.IdCardNumber && e != report.Exam);
            if (request.Sort == null || request.Sort.Count == 0)
            {
                request.Sort = [new DataGridRequest.SortModel { Selector = "creationTime", Desc = false }];
            }
            var sort = request.Sort[0];
            var sortQuery = sort.Selector switch
            {
                "accessionNumber" => sort.Desc ? query.OrderByDescending(e => e.AccessionNumber) : query.OrderBy(e => e.AccessionNumber),
                "patientName" => sort.Desc ? query.OrderByDescending(e => e.Patient.Name) : query.OrderBy(e => e.Patient.Name),
                "sex" => sort.Desc ? query.OrderByDescending(e => e.Patient.Sex) : query.OrderBy(e => e.Patient.Sex),
                "age" => sort.Desc ? query.OrderByDescending(e => e.Age) : query.OrderBy(e => e.Age),
                "examBodyPartiesText" => sort.Desc ? query.OrderByDescending(e => e.ExamBodyPartiesText) : query.OrderBy(e => e.ExamBodyPartiesText),
                "examItemsText" => sort.Desc ? query.OrderByDescending(e => e.ExamItemsText) : query.OrderBy(e => e.ExamItemsText),
                "examDevice" => sort.Desc ? query.OrderByDescending(e => e.ExamDevice.Name) : query.OrderBy(e => e.ExamDevice.Name),
                "examTime" => sort.Desc ? query.OrderByDescending(e => e.ExamTime) : query.OrderBy(e => e.ExamTime),
                "outPatientNumber" => sort.Desc ? query.OrderByDescending(e => e.OutPatientNumber) : query.OrderBy(e => e.OutPatientNumber),
                "inPatientNumber" => sort.Desc ? query.OrderByDescending(e => e.InPatientNumber) : query.OrderBy(e => e.InPatientNumber),
                "bedNumber" => sort.Desc ? query.OrderByDescending(e => e.BedNumber) : query.OrderBy(e => e.BedNumber),
                "applyNumber" => sort.Desc ? query.OrderByDescending(e => e.ApplyNumber) : query.OrderBy(e => e.ApplyNumber),
                "applyDepartment" => sort.Desc ? query.OrderByDescending(e => e.ApplyDepartment.Name) : query.OrderBy(e => e.ApplyDepartment.Name),
                "applyDoctor" => sort.Desc ? query.OrderByDescending(e => e.ApplyDoctor.Name) : query.OrderBy(e => e.ApplyDoctor.Name),
                "clinicalDiagnosis" => sort.Desc ? query.OrderByDescending(e => e.ClinicalDiagnosis) : query.OrderBy(e => e.ClinicalDiagnosis),
                "patientFrom" => sort.Desc ? query.OrderByDescending(e => e.PatientFrom.Name) : query.OrderBy(e => e.Patient.Name),
                "imageSeeing" => sort.Desc ? query.OrderByDescending(e => e.Report.ImageSeeing) : query.OrderBy(e => e.Report.ImageSeeing),
                "reportTime" => sort.Desc ? query.OrderByDescending(e => e.Report.ReportTime) : query.OrderBy(e => e.Report.ReportTime),
                "auditTime" => sort.Desc ? query.OrderByDescending(e => e.Report.AuditTime) : query.OrderBy(e => e.Report.AuditTime),
                _ => sort.Desc ? query.OrderByDescending(e => e.CreationTime) : query.OrderBy(e => e.CreationTime)
            };
            var exams = await AsyncExecuter.ToListAsync(sortQuery.Skip(request.Skip).Take(request.Take));
            return new WorkflowOutput
            {
                Success = true,
                Data = new DataGridDto
                {
                    Columns = new object[] {
                        new { DataField="oid", Caption="", visible=false },
                        new { DataField="reportId", Caption="", visible=false },
                        new { DataField="accessionNumber", Caption="检查号",Width=140 },
                        new { DataField="patientName", Caption="姓名" },
                        //性别
                        new { DataField="sex", Caption="性别" ,Width=70,CustomizeText="value=='Female' or value==1?'女':value==0 or value=='Male'?'男':'不详'"},
                        //年龄
                        new { DataField="age", Caption="年龄" ,Width=70},
                        //检查部位
                        new { DataField="examBodyPartiesText", Caption="检查部位" },
                        //检查项目
                        new { DataField="examItemsText", Caption="检查项目" },
                        //检查设备
                        new { DataField="examDevice", Caption="检查设备",Width=90 },
                        //检查日期
                        new { DataField="examTime", Caption="检查日期",DataType="datetime" },
                        //门诊号
                        new { DataField="outPatientNumber", Caption="门诊号" },
                        //住院号
                        new { DataField="inPatientNumber", Caption="住院号" },
                        //床位号
                        new { DataField="bedNumber", Caption="床位号",Width=80 },
                        //申请单号
                        new { DataField="applyNumber", Caption="申请单号" },
                        //申请科室
                        new { DataField="applyDepartment", Caption="申请科室",Width=90 },
                        //申请医生
                        new { DataField="applyDoctor", Caption="申请医生",Width=90 },
                        //临床诊断
                        new { DataField="clinicalDiagnosis", Caption="临床诊断" ,Width=200},
                        //患者来自
                        new { DataField="patientFrom", Caption="患者来自",Width=90 },
                        //影像所见
                        new { DataField="imageSeeing", Caption="影像所见",Width=240 },
                        //报告日期
                        new { DataField="reportTime", Caption="报告日期",DataType="datetime" },
                        //审核日期
                        new { DataField="auditTime", Caption="审核日期",DataType="datetime" }
                    },
                    Rows = exams.Select(e => new
                    {
                        e.Oid,
                        e.AccessionNumber,
                        ReportId = e.Report?.Id,
                        PatientName = e.Patient?.Name,
                        e.Patient?.Sex,
                        e.Age,
                        e.ExamBodyPartiesText,
                        e.ExamItemsText,
                        ExamDevice = e.ExamDevice?.Name,
                        e.ExamTime,
                        e.OutPatientNumber,
                        e.InPatientNumber,
                        e.BedNumber,
                        e.ApplyNumber,
                        ApplyDepartment = e.ApplyDepartment?.Name,
                        ApplyDoctor = e.ApplyDoctor?.Name,
                        e.ClinicalDiagnosis,
                        PatientFrom = e.PatientFrom?.Name,
                        e.Report?.ImageSeeing,
                        e.Report?.ReportTime,
                        e.Report?.AuditTime
                    }),
                    TotalCount = query.Count()
                }
            };
        }
        catch (Exception ex)
        {
            Logger.LogException(ex);
            await _unitOfWorkManager.Current.RollbackAsync();
            return new WorkflowOutput
            {
                Success = false,
                Error = ex.Message
            };
        }
    }

    public async Task<WorkflowOutput> GetExamFormsAsync(Guid reportId, DataGridRequest request)
    {
        try
        {
            var report = await _reportRepository.GetAsync(reportId);
            return new WorkflowOutput
            {
                Success = true,
                Data = new DataGridDto
                {
                    Columns = new object[] {
                        new { DataField="oid", Caption="", visible=false },
                        new { DataField="formPath", Caption="单据路径" },
                        new { DataField="formType", Caption="单据类型" }
                    },
                    Rows = report.Exam.ExamForms.OrderBy(e => e.CreationTime).Select(e => new
                    {
                        e.Oid,
                        e.FormPath,
                        FormType = e.FormType.Name
                    }),
                    TotalCount = report.Exam.ExamForms.Count
                }
            };
        }
        catch (Exception ex)
        {
            Logger.LogException(ex);
            await _unitOfWorkManager.Current.RollbackAsync();
            return new WorkflowOutput
            {
                Success = false,
                Error = ex.Message
            };
        }
    }

    public async Task<WorkflowOutput> GetExamEventsAsync(Guid reportId, DataGridRequest request)
    {
        try
        {
            var report = await _reportRepository.GetAsync(reportId);
            return new WorkflowOutput
            {
                Success = true,
                Data = new DataGridDto
                {
                    Columns = new object[] 
                    {
                        new { DataField="oid", Caption="", visible=false },
                        new { DataField="eventType", Caption="事件类型" },
                        new { DataField="eventTime", Caption="事件时间",DataType="datetime" },
                        new { DataField="operatorName", Caption="操作人",Width=100 },
                        new { DataField="eventContent", Caption="备注",Width=250 }
                    },
                    Rows = report.Exam.ExamEvents.OrderBy(e => e.CreationTime).Select(e => new
                    {
                        e.Oid,
                        e.EventType,
                        e.EventContent,
                        e.EventTime,
                        OperatorName = e.Operator.Name
                    }),
                    TotalCount = report.Exam.ExamEvents.Count
                }
            };
        }
        catch (Exception ex)
        {
            Logger.LogException(ex);
            await _unitOfWorkManager.Current.RollbackAsync();
            return new WorkflowOutput
            {
                Success = false,
                Error = ex.Message
            };
        }
    }

    public async Task<WorkflowOutput> GetExamRemarksAsync(Guid reportId, DataGridRequest request)
    {
        try
        {
            var report = await _reportRepository.GetAsync(reportId);
            return new WorkflowOutput
            {
                Success = true,
                Data = new DataGridDto
                {
                    Columns = new object[] {
                        new { DataField="oid", Caption="", visible=false },
                        new { DataField="levelId", visible=false },
                        new { DataField="level", Caption="等级" ,Width=70},
                        new { DataField="content", Caption="内容",Width=200 },
                        new { DataField="userName", Caption="用户",Width=100 },
                        new { DataField="contentCreationTime", Caption="创建时间",DataType="datetime" },
                        new { DataField="contentUpdateTime", Caption="更新时间",DataType="datetime" }
                    },
                    Rows = report.Exam.ExamRemarks.OrderBy(e => e.CreationTime).Select(e => new
                    {
                        e.Oid,
                        LevelId = e.Level.Oid,
                        Level = e.Level.Name,
                        e.Content,
                        UserName = e.User.Name,
                        e.ContentUpdateTime,
                        e.ContentCreationTime
                    }),
                    TotalCount = report.Exam.ExamRemarks.Count
                }
            };
        }
        catch (Exception ex)
        {
            Logger.LogException(ex);
            await _unitOfWorkManager.Current.RollbackAsync();
            return new WorkflowOutput
            {
                Success = false,
                Error = ex.Message
            };
        }
    }
    public async Task<WorkflowOutput> GetExamAdvancedSearchViewAsync()
    {
        try
        {
            var workflowOutput = await _getExamAdvancedSearchView.InvokeAsync([]);
            return workflowOutput;
        }
        catch (Exception ex)
        {
            Logger.LogException(ex);
            await _unitOfWorkManager.Current.RollbackAsync();
            return new WorkflowOutput
            {
                Success = false,
                Error = ex.Message
            };
        }
    }
    public async Task<WorkflowOutput> GetExamsAsync(DataGridRequest request)
    {
        try
        {
            CriteriaOperator criteriaOperator = CriteriaOperator.And(CriteriaOperator.FromLambda<Exam>(e => e.ExamStatus > ExamStatus.Appointment));
            var result = await _examListService.GetListByFilterAsync(request, criteriaOperator, _examAdvancedSearchExpression, _getExamHeaders, null, null, BusinessObjects.Managements.Exams.ExamFilterType.Exam);
            return result;
        }
        catch (Exception ex)
        {
            Logger.LogException(ex);
            await _unitOfWorkManager.Current.RollbackAsync();
            return new WorkflowOutput
            {
                Success = false,
                Error = ex.Message
            };
        }
    }
    public async Task<WorkflowOutput> GetQueueAdvancedSearchViewAsync()
    {
        try
        {
            var workflowOutput = await _getQueueAdvancedSearchView.InvokeAsync([]);
            return workflowOutput;
        }
        catch (Exception ex)
        {
            Logger.LogException(ex);
            await _unitOfWorkManager.Current.RollbackAsync();
            return new WorkflowOutput
            {
                Success = false,
                Error = ex.Message
            };
        }
    }
    public async Task<WorkflowOutput> GetQueuesAsync(DataGridRequest request)
    {
        try
        {
            var startTime = Clock.Now.Hour > 12 ? Clock.Now.Date.AddHours(12) : Clock.Now.Date;
            var endTime = Clock.Now.AddDays(1).Date;
            var stationCode = _stationCodeProvider.GetStationCode();
            //本站点，当天的
            CriteriaOperator criteriaOperator = CriteriaOperator.FromLambda<Exam>(e =>
            e.ExamDevice.Station.Code == stationCode
            && e.ExamQueuing != null
            && e.ExamQueuing.StartTime >= startTime && e.ExamQueuing.EndTime < endTime
            && e.ExamStatus != ExamStatus.Create
            && e.ExamStatus != ExamStatus.Appointment
            && e.ExamStatus != ExamStatus.Cancellation);
            var result = await _examListService.GetListByFilterAsync(request,
                                                                     criteriaOperator,
                                                                     _expression,
                                                                     _getQueueHeaders,
                                                                     null,
                                                                     _getDefaultFilter,
                                                                     BusinessObjects.Managements.Exams.ExamFilterType.Queuing);
            return result;
        }
        catch (Exception ex)
        {
            Logger.LogException(ex);
            await _unitOfWorkManager.Current.RollbackAsync();
            return new WorkflowOutput
            {
                Success = false,
                Error = ex.Message
            };
        }
    }
}
